package utils

import (
	"reflect"
	"sort"
)

// 通用结构体排序
// 结构体排序，必须重写数组Len() Swap() Less()函数
type Bucket struct {
	Slice []interface{}                //承载以任意结构体为元素构成的Slice
	By    func(p, q *interface{}) bool //排序规则函数,当需要对新的结构体slice进行排序时，只需定义这个函数即可
}

// 数组长度Len()
func (this Bucket) Len() int {
	return len(this.Slice)
}

//元素交换
func (this Bucket) Swap(i, j int) {
	this.Slice[i], this.Slice[j] = this.Slice[j], this.Slice[i]
}

//比较函数，使用外部传入的by比较函数
func (this Bucket) Less(i, j int) bool {
	return this.By(&this.Slice[i], &this.Slice[j])
}

//按照字段排序，需要注意是否有该字段和字段类型
func StructSort(list []interface{}, field string, order string) {
	sort.Sort(Bucket{list, func(p, q *interface{}) bool {
		v := reflect.ValueOf(*p)  //反射获取值 ，如果没要panic
		i := v.FieldByName(field) //反射检测是否存在该字段，如果没要panic
		v = reflect.ValueOf(*q)
		j := v.FieldByName(field)
		//Kind 检测类型
		switch j.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			if order == "desc" {
				return i.Int() > j.Int()
			} else {
				return i.Int() < j.Int()
			}
		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			if order == "desc" {
				return i.Uint() > j.Uint()
			} else {
				return i.Uint() < j.Uint()
			}
		case reflect.Float32, reflect.Float64:
			if order == "desc" {
				return i.Float() > j.Float()
			} else {
				return i.Float() < j.Float()
			}
		case reflect.String:
			if order == "desc" {
				return i.String() > j.String()
			} else {
				return i.String() < j.String()
			}
		}
		return false
	}})
}
